<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <ItemGroup>
    <_SkipTestAssemblies Include="$(SkipTestAssemblies)" />
  </ItemGroup>

  <PropertyGroup>
      <TestAssemblyDir Condition="'$(TestAssemblyDir)' == ''">$(BaseOutputPathWithConfig)\tests\</TestAssemblyDir>
      <__TestRunHtmlLog Condition="'$(__TestRunHtmlLog)' == ''">$(__LogsDir)\TestRun.html</__TestRunHtmlLog>
      <__TestRunXmlLog Condition="'$(__TestRunXmlLog)' == ''">$(__LogsDir)\TestRun.xml</__TestRunXmlLog>
  </PropertyGroup>

  <Target Name="FindLegacyTestDirectories">
    <ItemGroup>
      <LegacyTestAssemblies Include="$(BaseOutputPathWithConfig)\**\*.XUnitWrapper.dll" />
      <TestAssemblies Include="@(LegacyTestAssemblies)" Exclude="@(_SkipTestAssemblies -> '$(TestAssemblyDir)%(Identity)\%(Identity).XUnitWrapper.dll')" />
    </ItemGroup>

    <Message Text= "LegacyTestAssemblies= @(LegacyTestAssemblies)"/>
    <Message Text= "TestAssemblies= @(TestAssemblies)"/>
    <Message Text= "_SkipTestAssemblies= @(_SkipTestAssemblies -> '$(TestAssemblyDir)%(Identity)\%(Identity).XUnitWrapper.dll')"/>
  </Target>

  <Target Name="FindMergedTestDirectories">
    <ItemGroup>
      <_MergedTestAssemblyMarkers Include="$(BaseOutputPathWithConfig)\**\*.MergedTestAssembly" />
      <MergedTestWrapperScripts Include="$([System.IO.Path]::ChangeExtension('%(_MergedTestAssemblyMarkers.Identity)', '.$(TestScriptExtension)'))" />
      <MergedTestWrapperScripts Update="@(MergedTestWrapperScripts)">
        <RedirectOutputToFile>$([System.IO.Path]::ChangeExtension('%(MergedTestWrapperScripts.Identity)', '.log'))</RedirectOutputToFile>
        <TestResultsXmlFile>$([System.IO.Path]::ChangeExtension('%(MergedTestWrapperScripts.Identity)', '.testResults.xml'))</TestResultsXmlFile>
        <RelativeResultsPath>$([System.IO.Path]::GetRelativePath('$(TestBinDir)', $([System.IO.Path]::GetDirectoryName('%(MergedTestWrapperScripts.Identity)'))))</RelativeResultsPath>
      </MergedTestWrapperScripts>
      <MergedTestWrapperScripts Update="@(MergedTestWrapperScripts)">
        <TestResultsCopyTo>$(__LogsDir)\$([MSBuild]::ValueOrDefault('%(MergedTestWrapperScripts.RelativeResultsPath)', '').Replace('/', '.').Replace('\', '.')).testRun.xml</TestResultsCopyTo>
      </MergedTestWrapperScripts>
    </ItemGroup>
  </Target>

  <Target Name="PrepareTestsToRun"
          DependsOnTargets="FindLegacyTestDirectories;FindMergedTestDirectories">

    <Error  Text=" The wrappers must be compiled and placed at $(TestAssemblyDir)\*\ before they can be run, Do a clean Test Run"
            Condition="'@(LegacyTestAssemblies)' == '' and '@(MergedTestWrapperScripts)' == ''" />

    <PropertyGroup>
      <ExcludeTraits Condition="'$(ExcludeTraits)'==''">category=outerloop;category=failing</ExcludeTraits>
      <!-- Run one assembly at a time to avoid excessive parallelism leading to test timeouts -->
      <ParallelRun Condition="'$(ParallelRun)'==''">collections</ParallelRun>
    </PropertyGroup>
    <ItemGroup>
      <IncludeTraitsItems Include="$(IncludeTraits)" />
      <ExcludeTraitsItems Include="$(ExcludeTraits)" />
    </ItemGroup>

    <Error Condition="'$(CORE_ROOT)' == ''" Text="CORE_ROOT is not set." />
    <PropertyGroup>
      <XunitConsoleRunner>$(CORE_ROOT)\xunit\xunit.console.dll</XunitConsoleRunner>

      <XunitArgs Condition="'$(TargetOS)' == 'android' or '$(TargetOS)' == 'iossimulator'">-parallel none</XunitArgs>
      <XunitArgs Condition="'$(TargetOS)' != 'android' and '$(TargetOS)' != 'iossimulator'">-parallel $(ParallelRun)</XunitArgs>
      <XunitArgs>$(XunitArgs) -html $(__TestRunHtmlLog)</XunitArgs>
      <XunitArgs>$(XunitArgs) -xml $(__TestRunXmlLog)</XunitArgs>
      <XunitArgs>$(XunitArgs) @(IncludeTraitsItems->'-trait %(Identity)', ' ')</XunitArgs>
      <XunitArgs>$(XunitArgs) @(ExcludeTraitsItems->'-notrait %(Identity)', ' ')</XunitArgs>

      <!-- Color output doesn't work well when capturing the output in the CI system -->
      <XunitArgs>$(XunitArgs) -nocolor</XunitArgs>
    </PropertyGroup>

    <!-- Work around cmd command length limit by using relative paths
         from working directory instead of full paths (see
         https://github.com/Microsoft/msbuild/issues/2530) -->
    <ItemGroup Condition="'$(RunningOnUnix)' != 'true'">
      <_TestAssembliesRelative Include="@(TestAssemblies -> Replace('$(BaseOutputPathWithConfig)', '.\'))" />
      <TestAssemblies Remove="@(TestAssemblies)" />
      <TestAssemblies Include="@(_TestAssembliesRelative)" />
    </ItemGroup>
  </Target>

  <Target Name="RunSingleMergedTest">
    <Exec Command="chmod +x $(TestWrapperScript)" WorkingDirectory="$(BaseOutputPathWithConfig)" EchoOff="true" Condition="'$(TargetOS)' != 'windows'" />
    <Exec Command="$(TestWrapperScript) &gt;$(RedirectOutputToFile) 2&gt;&amp;1" WorkingDirectory="$(BaseOutputPathWithConfig)" Timeout="$(__TestTimeout)" IgnoreExitCode="true">
      <Output TaskParameter="ExitCode" PropertyName="MergedTestExitCode" />
    </Exec>
    <Copy SourceFiles="$(TestResultsXmlFile)" DestinationFiles="$(TestResultsCopyTo)" Condition="'$(MergedTestExitCode)' == '0'" />
    <Message Importance="High" Text="Error running test group '$(TestWrapperScript)' - exit code $(MergedTestExitCode)" Condition="'$(MergedTestExitCode)' != '0'" />
  </Target>

  <Target Name="RunMergedTests" DependsOnTargets="PrepareTestsToRun">
    <ItemGroup>
      <_ProjectsToBuild Include="$(MSBuildThisFileFullPath)">
        <AdditionalProperties>TestWrapperScript=%(MergedTestWrapperScripts.Identity);RedirectOutputToFile=%(MergedTestWrapperScripts.RedirectOutputToFile);TestResultsXmlFile=%(MergedTestWrapperScripts.TestResultsXmlFile);TestResultsCopyTo=%(MergedTestWrapperScripts.TestResultsCopyTo)</AdditionalProperties>
      </_ProjectsToBuild>
    </ItemGroup>

    <MSBuild Projects="@(_ProjectsToBuild)" Targets="RunSingleMergedTest" BuildInParallel="true" Condition="'@(MergedTestWrapperScripts)' != ''" />
  </Target>

  <Target Name="RunLegacyTests" DependsOnTargets="PrepareTestsToRun">
      <!-- Run xunit with dotnet.
           We set roll-forward LatestMajor so that dotnet doesn't choose some old runtime that comes from
           the era when xunit.console.dll was built. -->
    <PropertyGroup>
      <XunitCommandLine>$(DotNetCli) --roll-forward latestmajor $(XunitConsoleRunner) @(TestAssemblies->'%(Identity)', ' ') $(XunitArgs)</XunitCommandLine>
    </PropertyGroup>

    <Exec Command="$(XunitCommandLine)"
          WorkingDirectory="$(BaseOutputPathWithConfig)"
          Condition="'@(TestAssemblies)' != ''" />
  </Target>

  <Target Name="RunTests" DependsOnTargets="RunMergedTests;RunLegacyTests" Condition="'$(SkipTests)' != 'True'">
    <!-- TODO - merged reporting? -->
  </Target>
</Project>
